﻿using Ewell.BizComponent.Charge.Model;
using Ewell.BizComponent.Charge.UI.VM;
using Ewell.BizComponent.Service.Model.Dto;
using Ewell.BizComponent.Service.Model.Request;
using Ewell.BizComponent.Service.Model.Response;
using Ewell.BizComponent.Service.Server;
using Ewell.Interface.Common.Model.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Input;

namespace Ewell.BizComponent.Charge.UI.VM
{
    public class CashierVm : CashierBaseVm
    {
        public CashierVm() { }
        public CashierVm(ChargingInfoVm chargingInfo):this()
        {
            this.chargingInfo = chargingInfo;
        }
        public CashierVm(ChargingInfoVm chargingInfo,List<PayWayVm> payWayList) : this(chargingInfo)
        {
            this.payWayList = payWayList;
            this.prestorePayWay= this.payWayList.FirstOrDefault(f=>f.no== "HIS001");
            this.otherPayWayList = this.payWayList.Where(f=>f.no!= "HIS001").ToList();
        }
        /// <summary>
        /// 当前窗体
        /// </summary>
        public Window localWindow { get; set; }
        /// <summary>
        /// 支付方式
        /// </summary>
        private List<PayWayVm> _payWayList;
        public List<PayWayVm> payWayList
        {
            get => _payWayList; set
            {
                if (value != _payWayList)
                {
                    _payWayList = value;
                    OnPropertyChanged(nameof(payWayList));
                }
            }
        }
        /// <summary>
        /// 预存账户支付方式
        /// </summary>
        private PayWayVm _prestorePayWay;
        public PayWayVm prestorePayWay
        {
            get => _prestorePayWay;
            set
            {
                if(value != _prestorePayWay)
                {
                    _prestorePayWay = value;
                    OnPropertyChanged(nameof(prestorePayWay));
                }
            }
        }
        /// <summary>
        /// 预存账户之外的支付方式
        /// </summary>
        public List<PayWayVm> _otherPayWayList;
        public List<PayWayVm> otherPayWayList
        {
            get => _otherPayWayList; set
            {
                if (value != _otherPayWayList)
                {
                    _otherPayWayList = value;
                    OnPropertyChanged(nameof(otherPayWayList));
                }
            }
        }
        /// <summary>
        /// 单支付方式下选中的支付方式
        /// </summary>
        private PayWayVm _selectPayWay;
        public PayWayVm selectPayWay
        {
            get=> _selectPayWay;
            set
            {
                if (value != _selectPayWay)
                {
                    _selectPayWay = value;
                    OnPropertyChanged(nameof(selectPayWay));
                }
            }
        }
        /// <summary>
        /// 患者信息
        /// </summary>
        private PatientVm _patientVm;
        public PatientVm patientVm
        {
            get => _patientVm; set
            {
                if (value != _patientVm)
                {
                    _patientVm = value;
                    OnPropertyChanged(nameof(patientVm));
                }
            }
        }
        /// <summary>
        /// 收费信息
        /// </summary>
        private ChargingInfoVm _chargingInfo;
        public ChargingInfoVm chargingInfo
        {
            get => _chargingInfo; set
            {
                if (_chargingInfo != value)
                {
                    _chargingInfo = value;
                    OnPropertyChanged(nameof(chargingInfo));
                }
            }
        }
        /// <summary>
        /// 收费结果通知
        /// </summary>
        public event EventHandler<CashierContext> NoticeChargeResult;
        /// <summary>
        /// 取消收费通知
        /// </summary>
        public event EventHandler<CashierContext> NoticeChargeCancel;

        /// <summary>
        /// 结算事件
        /// </summary>
        public ICommand settlement => new RelayCommand((object param) =>
        {
            this.context.cashierMainVm.next();
        });
        /// <summary>
        /// 取消结算
        /// </summary>
        public ICommand settlementCancel => new RelayCommand((object param) =>
        {
            var onlinePayList = payWayList.Where(x => x.interfaceId.HasValue && x.paySuccess == true)?.ToList();
            if (onlinePayList.Count > 0)
            {
                OnlinePayVm onlinePayVm = new OnlinePayVm()
                {
                    patientVm = this.patientVm,
                    chargingInfo = this.chargingInfo,
                    payWayList = onlinePayList,
                };
                OnlinePayFrm onlinePayFrm = new OnlinePayFrm(onlinePayVm);
                onlinePayFrm.Owner = this.localWindow;
                onlinePayVm.localWindows = onlinePayFrm;
                onlinePayFrm.RefundAll();
            }
            
            if (payWayList.Any(a => a.interfaceId.HasValue && a.paySuccess == true))
            {
                MessageBox.Show("还有未退费的支付金额！");
                return;
            }
            NoticeChargeCancel?.Invoke(this, this.context);
        });
        /// <summary>
        /// 支付失败重试
        /// </summary>
        public ICommand rePay => new RelayCommand((object payWay)=>
        {
            PayWayVm payWayVm = payWay as PayWayVm;
            //this.Pay(payWayVm);
            var rePayWayList = this.payWayList.Where(w => w.no == payWayVm.no).ToList();
            rePayWayList.ForEach(x => x.payQrCode = string.Empty);
            OnlinePayVm onlinePayVm = new OnlinePayVm()
            {
                patientVm = this.patientVm,
                chargingInfo = this.chargingInfo,
                payWayList = rePayWayList,
            };
            OnlinePayFrm onlinePayFrm = new OnlinePayFrm(onlinePayVm);
            onlinePayFrm.Owner = this.localWindow;
            onlinePayVm.localWindows = onlinePayFrm;
            onlinePayFrm.PayAll();
        });

        public override CashierStepVm.StepLoading stepLoading => new CashierStepVm.StepLoading(context =>
        {
            this.context = context;
            this.payWayList= context.cashierMainVm.payWayList;
            this.prestorePayWay = this.payWayList.FirstOrDefault(f => f.no == "HIS001");
            this.otherPayWayList = this.payWayList.Where(f => f.no != "HIS001").ToList();
            this.patientVm= context.patientVm;
            this.chargingInfo= context.chargingInfo;
            context.cashierMainVm.currentStep.StepState = FunnyArts.Wpf.ControlLibrary.Model.StepStatus.Running;
            context.cashierMainVm.currentStep.page = new CashierFrm(this);
        });

        public override CashierStepVm.StepHandler stepHandler => new CashierStepVm.StepHandler(context =>
        {
            context.chargeResult = new ChargeResultVm()
            {
                success = false,
                settlementId = chargingInfo.settlementId,
            };

            //校验
            if (payWayList.Where(w => w.amount > 0).Sum(w => w.amount) != this.chargingInfo.recAmount)
            {
                MessageBox.Show("支付金额不等于应收金额!");
                return;
            }
            var onlinePayList = payWayList.Where(x => x.interfaceId.HasValue && x.amount > 0 && x.paySuccess != true)?.ToList();
            if (onlinePayList.Count > 0)
            {
                onlinePayList.ForEach(x => x.payQrCode = string.Empty);
                OnlinePayVm onlinePayVm = new OnlinePayVm()
                {
                    patientVm = this.patientVm,
                    chargingInfo = this.chargingInfo,
                    payWayList = onlinePayList,
                };
                OnlinePayFrm onlinePayFrm = new OnlinePayFrm(onlinePayVm);
                onlinePayFrm.Owner = this.localWindow;
                onlinePayVm.localWindows = onlinePayFrm;
                onlinePayFrm.PayAll();
            }

            if (payWayList.Any(a => a.interfaceId.HasValue && a.amount > 0 && a.paySuccess != true))
            {
                var payWayFail = payWayList.FirstOrDefault(f => f.interfaceId.HasValue && f.amount > 0 && f.paySuccess != true);
                MessageBox.Show($"支付方式【{payWayFail.name}】支付金额【{payWayFail.amount}】失败！请重试!");
                return;
            }
            //结算
            List<PayRecordDto> payRecords = new List<PayRecordDto>();
            foreach (var payWay in payWayList.Where(w => w.amount > 0 && ((w.interfaceId.HasValue && w.paySuccess == true) || !w.interfaceId.HasValue)))
            {
                PayRecordDto payRecordDto = new PayRecordDto()
                {
                    payAmount = payWay.amount,
                    payWayId = payWay.no,
                    thirdPartTranId = payWay.payTxnNo,
                };
                payRecords.Add(payRecordDto);
            }

            OutSettlementRequest settlementRequest = new OutSettlementRequest()
            {
                settlementInfo = new SettlementDto()
                {
                    settlementId = chargingInfo.settlementId.ToString(),
                    payTypeCoding = chargingInfo.settlementTypeCode,
                    amount = chargingInfo.amount.Value,
                    discountAmount = chargingInfo.discountAmount.Value,
                    insurAmount = chargingInfo.insurAmount??0,
                    selfPayAmount = chargingInfo.recAmount.Value,
                    payRecordList = payRecords,
                }
            };
            OutSettlementServer outSettlementServer = new OutSettlementServer();
            try
            {
                OutSettlementResponse response = outSettlementServer.Settlement(settlementRequest);
            }
            catch (SpeedException ex)
            {
                MessageBox.Show($"收费失败!,{ex.Message}");
                //退支付
                if (payWayList.Any(a => a.interfaceId.HasValue && a.amount > 0 && a.paySuccess == true))
                {
                    OnlinePayVm onlinePayVm = new OnlinePayVm()
                    {
                        patientVm = this.patientVm,
                        chargingInfo = this.chargingInfo,
                        payWayList = payWayList.Where(a => a.interfaceId.HasValue && a.amount > 0 && a.paySuccess == true).ToList(),
                    };
                    OnlinePayFrm onlinePayFrm = new OnlinePayFrm(onlinePayVm);
                    onlinePayFrm.Owner = this.localWindow;
                    onlinePayVm.localWindows = onlinePayFrm;
                    onlinePayFrm.RefundAll();
                }
                return;
            }
            catch (Exception ex)
            {
                MessageBox.Show($"收费失败!,{ex.Message}");
                //退支付
                if (payWayList.Any(a => a.interfaceId.HasValue && a.amount > 0 && a.paySuccess == true))
                {
                    OnlinePayVm onlinePayVm = new OnlinePayVm()
                    {
                        patientVm = this.patientVm,
                        chargingInfo = this.chargingInfo,
                        payWayList = payWayList.Where(a => a.interfaceId.HasValue && a.amount > 0 && a.paySuccess == true).ToList(),
                    };
                    OnlinePayFrm onlinePayFrm = new OnlinePayFrm(onlinePayVm);
                    onlinePayFrm.Owner = this.localWindow;
                    onlinePayVm.localWindows = onlinePayFrm;
                    onlinePayFrm.RefundAll();
                }
                return;
            }
            context.chargeResult.success = true;
            NoticeChargeResult?.Invoke(this, context);
        });
    }
}
